#pragma once
#include <iostream>
#include <optional>
#include "log.hpp"
#include <fstream>
#include <unordered_map>
namespace MY
{   
    const std::string distDefaultSep=": ";
    const std::string distDefaultPath="./dist.txt";
    class dist
    {
    private:
        std::string _filePath;
        std::string _sep;
        std::unordered_map<std::string,std::string>_dist_to_e;
        std::unordered_map<std::string,std::string>_dist_to_c;
    public:
        dist(const std::string& path=distDefaultPath
            ,const std::string& sep=distDefaultSep);
        ~dist();
        inline bool init();
        inline std::optional<std::string>
        translate(const std::string& str);
    };

    dist::dist(const std::string& path,const std::string& sep)
    :_filePath(path)
    ,_sep(sep)
    {
    }

    dist::~dist()
    {
    }

    inline bool dist::init()
    {
        LOG(logLevel::INFO)<<"Getting the data";
        std::ifstream in(_filePath);
        if(!in.is_open()){
            LOG(logLevel::ERROR)<<"Failed to get the data ";
            return false;
        }
        std::string buffer;
        std::string c_str;
        std::string e_str;
        while(std::getline(in,buffer)){
            int pos=buffer.find(_sep);
            if(pos ==std::string::npos){
                LOG(logLevel::ERROR)<<"Failed to get word "+buffer;
                continue;
            }
            c_str=buffer.substr(0,pos);
            e_str=buffer.substr(pos+_sep.size());
            if(c_str.empty()||e_str.empty()){
                LOG(logLevel::ERROR)<<buffer+":is not intact";
                continue;
            }
            _dist_to_e.emplace(c_str,e_str);
            _dist_to_c.emplace(e_str,c_str);
            LOG(logLevel::INFO)<<"Succeed to get "+buffer;
        }
        LOG(logLevel::INFO)<<"Finish loading";
        return true;
    }

    inline std::optional<std::string> dist::translate
    (const std::string& str)
    {
        LOG(logLevel::INFO)<<"Get into translate model";
        auto it=_dist_to_e.find(str);
        if(it != _dist_to_e.end()){
            LOG(logLevel::INFO)<<"Succeed to get "+it->second;
            return it->second;
        }
        it=_dist_to_c.find(str);
        if(it != _dist_to_c.end()){
            LOG(logLevel::INFO)<<"Succeed to get "+it->second;
            return it->second;
        }
    
        LOG(logLevel::DEBUG)<<"Failed translate "+str;
        return std::nullopt;
    }
}